package com.asana.resteasy.api.client;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import com.asana.resteasy.api.bean.AsanaData;
import com.asana.resteasy.api.bean.AsanaPost;
import com.asana.resteasy.api.bean.Project;
import com.asana.resteasy.api.bean.Story;
import com.asana.resteasy.api.bean.Tag;
import com.asana.resteasy.api.bean.Task;
import com.asana.resteasy.api.bean.User;
import com.asana.resteasy.api.exception.AsanaException;
import com.asana.resteasy.api.util.AsanaSearchBy;
import com.asana.resteasy.api.util.GSonParser;
import com.asana.resteasy.api.util.Log;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class Asana {

	public Asana(String key) {
		super();
		this.key = key;
		Log.init();
	}

	private String key = "n3DEJPR.zh0CBzXwu5cm4fLl7fcmkBOG"; 

	private Gson getGSon(){
		Gson gson = new GsonBuilder()
		   .registerTypeAdapter(Date.class, GSonParser.serializeDate)
		   .registerTypeAdapter(Date.class, GSonParser.deserializeDate).create();

		return gson;
	}
	
	public void updateTaskStatus(String idTask,boolean completed){
		AsanaRestInterface restClient = RestClientFactory.connect(key);
		AsanaPost post = new AsanaPost();
		post.getData().put("completed", completed);
		restClient.updateTask(idTask, getGSon().toJson(post));
	}
	
	public void addComment(String idTask,String text){
		AsanaRestInterface restClient = RestClientFactory.connect(key);
		AsanaPost post = new AsanaPost();
		post.getData().put("text", text);
		restClient.addTaskCommand(idTask, "stories", getGSon().toJson(post));
	}
	
	public Task getTask(String idTask){
		AsanaRestInterface restClient = RestClientFactory.connect(key);
		String response = restClient.getTask(idTask);
		Log.MESSAGE.info("["+System.nanoTime()+"] Response : " + response);
		Gson gson = getGSon();
		Task task = gson.fromJson(getDataAsObject(response), Task.class);
		return task;
	}
	
	public List<Task> getTasks(String id,int searchBy){
		AsanaRestInterface restClient = RestClientFactory.connect(key);
		String response = null;
		
		switch (searchBy) {
		case AsanaSearchBy.USER:
			response = restClient.getTasksFromUser(id);	
		break;
		case AsanaSearchBy.PROJECT:
			response = restClient.getTasksFromProject(id);	
		break;
		case AsanaSearchBy.WORKSPACE:
			response = restClient.getTasksFromWorkspace(id);	
		break;
		case AsanaSearchBy.TAG:
			response = restClient.getTasksFromTag(id);	
		break;
		default:
		break;
		}
		
		Log.MESSAGE.info("["+System.nanoTime()+"] Response : " + response);
		List<Task> tasks = new ArrayList<Task>();
		JsonArray jsonArray = getDataAsArray(response);
		for (JsonElement el : jsonArray){
			Gson gson = getGSon();
			tasks.add(gson.fromJson(el, Task.class));
		}
			
		return tasks;
	}
	
	public User getUser(String idUser){
		AsanaRestInterface restClient = RestClientFactory.connect(key);
		String response = restClient.getUser(idUser);
		Log.MESSAGE.info("["+System.nanoTime()+"] Response : " + response);
		Gson gson = getGSon();
		User user = gson.fromJson(getDataAsObject(response), User.class);
		return user;
	}
	
	public User getMe(){
		AsanaRestInterface restClient = RestClientFactory.connect(key);
		String response = restClient.getUser("me");
		Log.MESSAGE.info("["+System.nanoTime()+"] Response : " + response);
		Gson gson = getGSon();
		User user = gson.fromJson(getDataAsObject(response), User.class);
		return user;
	}
	
	public Task createTask(AsanaPost request){
		AsanaRestInterface restClient = RestClientFactory.connect(key);
		String response = restClient.createTask(getGSon().toJson(request));
		Log.MESSAGE.info("["+System.nanoTime()+"] Response : " + response);
		Gson gson = getGSon();
		Task task = gson.fromJson(getDataAsObject(response), Task.class);
		return task;
	}
	
	public Tag createTag(String idWorkspace,String description){
		AsanaRestInterface restClient = RestClientFactory.connect(key);
		AsanaPost request  = new AsanaPost();
		request.getData().put("name", description);
		String response = restClient.createTag(idWorkspace,getGSon().toJson(request));
		Log.MESSAGE.info("["+System.nanoTime()+"] Response : " + response);
		Gson gson = getGSon();
		Tag obj = gson.fromJson(getDataAsObject(response), Tag.class);
		return obj;
	}
	
	public void addTag(String idTag,String idTask){
		AsanaRestInterface restClient = RestClientFactory.connect(key);
		AsanaPost request  = new AsanaPost();
		request.getData().put("tag", idTag);
		String response = restClient.addTaskCommand(idTask, "addTag", getGSon().toJson(request));
		//String response = restClient.addTagToTask(idTask, getGSon().toJson(request));
		Log.MESSAGE.info("["+System.nanoTime()+"] Response : " + response);
	}
	
	public void deleteTask(String idTask){
		AsanaRestInterface restClient = RestClientFactory.connect(key);
		restClient.deleteTask(idTask);
	}
	
	public void deleteTask(Task task){
		deleteTask(task.getId());
	}
	
	public List<Project> getProjects(){
		AsanaRestInterface restClient = RestClientFactory.connect(key);
		String response = restClient.getProjects();
		Log.MESSAGE.info("["+System.nanoTime()+"] Response : " + response);
		
		List<Project> projects = new ArrayList<Project>();
		JsonArray jsonArray = getDataAsArray(response);
		for (JsonElement el : jsonArray){
			Gson gson = new Gson();	
			projects.add(gson.fromJson(el, Project.class));
		}
			
		return projects;
	}
	
	public List<User> getUsers(){
		AsanaRestInterface restClient = RestClientFactory.connect(key);
		String response = restClient.getUser("");
		Log.MESSAGE.info("["+System.nanoTime()+"] Response : " + response);
		
		List<User> users = new ArrayList<User>();
		JsonArray jsonArray = getDataAsArray(response);
		for (JsonElement el : jsonArray){
			Gson gson = new Gson();	
			users.add(gson.fromJson(el, User.class));
		}
			
		return users;
	}
	
	public List<Tag> getTags() throws AsanaException{
		try {
			AsanaRestInterface restClient = RestClientFactory.connect(key);
			String response = restClient.getTag("");
			Log.MESSAGE.info("["+System.nanoTime()+"] Response : " + response);
			
			List<Tag> tags = new ArrayList<Tag>();
			JsonArray jsonArray = getDataAsArray(response);
			for (JsonElement el : jsonArray){
				Gson gson = new Gson();	
				tags.add(gson.fromJson(el, Tag.class));
			}
				
			return tags;
		} catch (Exception e){
			throw new AsanaException();
		}
	}
	
	public Tag getTag(String id) throws AsanaException{
		try {
			AsanaRestInterface restClient = RestClientFactory.connect(key);
			String response = restClient.getTag(id);
			Log.MESSAGE.info("["+System.nanoTime()+"] Response : " + response);
			Gson gson = getGSon();
			Tag obj = gson.fromJson(getDataAsObject(response), Tag.class);			
			return obj;
		} catch (Exception e){
			throw new AsanaException();
		}
		
	}
	
	public List<Story> getTaskStories(String id) throws AsanaException{
		try {
			AsanaRestInterface restClient = RestClientFactory.connect(key);
			String response = restClient.getTaskStory(id);
			Log.MESSAGE.info("["+System.nanoTime()+"] Response : " + response);
			
			List<Story> stories = new ArrayList<Story>();
			JsonArray jsonArray = getDataAsArray(response);
			for (JsonElement el : jsonArray){
				Gson gson = getGSon();
				stories.add(gson.fromJson(el, Story.class));
			}
				
			return stories;
		} catch (Exception e){
			e.printStackTrace();
			throw new AsanaException();
		}
	}
	
	
	private JsonElement getDataAsObject(String jsonMesssage){
		Gson gson = getGSon();
		JsonElement jelement = new JsonParser().parse(jsonMesssage);
		JsonObject  jobject = jelement.getAsJsonObject();
		jobject = jobject.getAsJsonObject("data");
	    return jobject;
	}
	
	private JsonArray getDataAsArray(String jsonMesssage){
		Gson gson = getGSon();
		JsonElement jelement = new JsonParser().parse(jsonMesssage);
		JsonObject  jobject = jelement.getAsJsonObject();
		return jobject.getAsJsonArray("data");
	}

}
